package com.example.wechathook.hook;

import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import static de.robv.android.xposed.XposedHelpers.setStaticObjectField;

import java.net.NetworkInterface;

import android.content.ContentResolver;
import android.net.wifi.WifiInfo;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;

import com.example.wechathook.util.PreferenceUtils;
import com.example.wechathook.util.Utils;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

/**
 * 系统信息hook
 * 
 * @author chencq
 *
 */
public class SystemInfoHook extends BaseHook{

	@Override
	public void hook(final XC_LoadPackage.LoadPackageParam lpp) {

		boolean isOpen = PreferenceUtils.isSystemSwitch();
		if (!isOpen) {
			return;
		}

		findAndHookMethod("android.os.SystemProperties", lpp.classLoader, "get", String.class, new XC_MethodHook() {
			@Override
			protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
				String board = PreferenceUtils.board();
				if (Utils.isNotNull(board)) {
					setStaticObjectField(Build.class, "BOARD", board);
				}

				String device = PreferenceUtils.device();
				if (Utils.isNotNull(device)) {
					setStaticObjectField(Build.class, "DEVICE", device);
				}

				String display = PreferenceUtils.display();
				if (Utils.isNotNull(display)) {
					setStaticObjectField(Build.class, "DISPLAY", display);
				}

				String fingerprint = PreferenceUtils.fingerprint();
				if (Utils.isNotNull(fingerprint)) {
					setStaticObjectField(Build.class, "FINGERPRINT", fingerprint);
				}

				String host = PreferenceUtils.host();
				if (Utils.isNotNull(host)) {
					setStaticObjectField(Build.class, "HOST", host);
				}

				String manufacturer = PreferenceUtils.manufacturer();
				if (Utils.isNotNull(manufacturer)) {
					setStaticObjectField(Build.class, "MANUFACTURER", manufacturer);
				}

				String model = PreferenceUtils.model();
				if (Utils.isNotNull(model)) {
					setStaticObjectField(Build.class, "MODEL", model);
				}

				String product = PreferenceUtils.product();
				if (Utils.isNotNull(product)) {
					setStaticObjectField(Build.class, "PRODUCT", product);
				}

				String tags = PreferenceUtils.tags();
				if (Utils.isNotNull(tags)) {
					setStaticObjectField(Build.class, "TAGS", tags);
				}

				String type = PreferenceUtils.type();
				if (Utils.isNotNull(type)) {
					setStaticObjectField(Build.class, "TYPE", type);
				}

				String user = PreferenceUtils.user();
				if (Utils.isNotNull(user)) {
					setStaticObjectField(Build.class, "USER", user);
				}

				super.beforeHookedMethod(param);
			}
		});

		findAndHookMethod(TelephonyManager.class.getCanonicalName(), lpp.classLoader, "getDeviceId",
				new XC_MethodHook() {
					@Override
					protected void afterHookedMethod(MethodHookParam param) throws Throwable {
						String imei = PreferenceUtils.imei();
						if (Utils.isNotNull(imei)) {
							param.setResult(imei);
						} else {
							super.afterHookedMethod(param);
						}
					}
				});

		findAndHookMethod(TelephonyManager.class.getCanonicalName(), lpp.classLoader, "getSimSerialNumber",
				new XC_MethodHook() {
					@Override
					protected void afterHookedMethod(MethodHookParam param) throws Throwable {
						String simNumber = PreferenceUtils.simNumber();
						if (Utils.isNotNull(simNumber)) {
							param.setResult(simNumber);
						} else {
							super.afterHookedMethod(param);
						}
					}
				});

		findAndHookMethod(Settings.Secure.class.getCanonicalName(), lpp.classLoader, "getString",
				ContentResolver.class, String.class, new XC_MethodHook() {
					@Override
					protected void afterHookedMethod(MethodHookParam param) throws Throwable {
						String androidId = PreferenceUtils.androidId();
						if (param.args.length == 2 && (param.args[1] instanceof String)) {
							if (Settings.Secure.ANDROID_ID.contentEquals((String) param.args[1])
									&& Utils.isNotNull(androidId)) {
								param.setResult(androidId);
							} else {
								super.afterHookedMethod(param);
							}
						} else {
							super.afterHookedMethod(param);
						}
					}
				});

		findAndHookMethod(WifiInfo.class.getCanonicalName(), lpp.classLoader, "getMacAddress", new XC_MethodHook() {
			@Override
			protected void afterHookedMethod(MethodHookParam param) throws Throwable {
				String mac = PreferenceUtils.mac();
				if (Utils.isNotNull(mac)) {
					param.setResult(mac);
				} else {
					super.afterHookedMethod(param);
				}
			}
		});

		findAndHookMethod(NetworkInterface.class.getCanonicalName(), lpp.classLoader, "getHardwareAddress",
				new XC_MethodHook() {
					@Override
					protected void afterHookedMethod(MethodHookParam param) throws Throwable {
						String mac = PreferenceUtils.mac();
						if (Utils.isNotNull(mac)) {
							param.setResult(Utils.hexStringToByteArray(mac.replace(":", "")));
						} else {
							super.afterHookedMethod(param);
						}
					}
				});
		

	}
}
